home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_9.zip
/
LIB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-27
|
18KB
|
703 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
#include "hdr.h"
#include "vars.h"
#include "libhdr.h"
#include "ifile.h"
#include "dbxp.h"
#include "miscp.h"
#include "smiscp.h"
#include "setp.h"
#include "libfp.h"
#include "librp.h"
#include "libp.h"
static char *update_lib_maps_remove(char *, int);
static void sym_restore(Symbol);
/* keeping unit_nodes as tuple, unit_nodes_now is number of actual elements */
void unit_nodes_add();
/*
* Procedures in this module serve two phases of the compiler:
*
* (1) maintaining a program library during semantic translation,
*
* (2) reading in and writing out the intermediate files associated with
* semantic processing.
*
* Three types of files are used here:
*
* AIS files information generated during the translation of a source
* file,
*
* TRE files intermediate code
*
* LIB files directory to units in AIS files,
*
* LIB files and AIS files are each organized as a pair of maps whose
* domain elements are unique compilation unit names such as:
*
* ['subprog spec', 'MAIN']
*
* ['spec', 'MATH_PACK']
*
* ['subprog', 'SIN', 'MATH_PACK']
*
* The first string in these names is gives the unit's class as seen
* by the binder:
*
* 'subprog spec', 'subprog' -- subprogram specifications & bodies
*
* 'spec', 'body' -- package specifications & module bodies
*
* The second string is the name of the compilation unit itself. If
* this is a subunit, the remaining names are those of its enclosing
* scopes.
*
* A LIB file is a pair of maps from these unique names to the
* appropriate AIS files names:
*
* (1) LIB_UNIT, which indicates the file containing the
* translation of each compilation unit, and
*
* (2) LIB_STUB, which indicates the file containing the
* translation of the stub of the subunit.
*
* Each AIS file is a parallel pair of maps, again from unique names,
* containing the translation of each compilation unit and the
* environment of each stub. For convenience, these two maps are split
* into five within the translator itself:
*
* COMP_DATE
* A map for each compilation unit to compilation dates & times
* checking consistency). Dates themselves are a tuple including
* the date and clock time of translation, and an indication of
* the order of compilation within a single session.
*
* PRE_COMP
* List of units that should have been compiled before this one.
*
* UNIT_DECL
* The declarations that can be seen by other units, or that will
* be needed later by the translator.
*
* STUB_ENV
* The environment at the point where the stub was declared.
*
* During the initialization of the compiler, several predefined
* library units are read in and permanently installed. These units
* are not included explicitly in the library, but may be accessed
* as if they were. The information from their AIS files is stored in
* the map 'predef_map' (local to this module), and a set of those
* currently available (not displaced by a user's unit) is maintained
* in the global variable PREDEF_UNITS. For simplicity, these
* predefined units may not have stubs.
*
* The semantic analyser has access to compilation information in the
* AIS files through the procedures RETRIEVE and STUB_RETRIEVE. When
* called, these two procedures try to make the requested information
* available in the five compilation maps listed above (it may read
* an AIS file, copy from predef_map or the information may
* already be present). If successful, they return the value TRUE,
* otherwise they return FALSE.
*
* UPDATE_LIB_MAPS is called to do some housekeeping when a new
* compilation unit is started.
*
* The user may choose to not use the separate compilation facility
* and put every compilation unit into one file. In this case,
* the LIB file can be omitted, since its role is to group several
* AIS files together. Furthermore, since AIS files contain all of
* the information produced by a translation session, more than
* one LIB file may refer to a single AIS file.
*/
extern IFILE *LIBFILE;
int init_predef() /*;init_predef*/
{
char *lname;
char *t_name;
extern char *PREDEFNAME;
lname = libset(PREDEFNAME); /* set PREDEF library as library */
LIBFILE = ifopen("predef", "lib", "r", 0);
t_name =libset(lname); /* restore prior library */
return(read_lib()); /* number of units read */
}
char *predef_unit_name(int i) /*;predef_unit_name*/
{
static char *predef_unit_names[15] = { "",
"spSYSTEM", "spIO_EXCEPTIONS", "spSEQUENTIAL_IO",
"boSEQUENTIAL_IO", "spDIRECT_IO", "boDIRECT_IO",
"spTEXT_IO", "boTEXT_IO", "spCALENDAR", "boCALENDAR",
"ssUNCHECKED_DEALLOCATION", "suUNCHECKED_DEALLOCATION",
"ssUNCHECKED_CONVERSION", "suUNCHECKED_CONVERSION"};
return predef_unit_names[i];
}
int predef_node_count(int i) /*;predef_node_count*/
{
static int node_count[15] = {0,166, 29, 449, 5, 620, 5, 2654, 17, 470, 5,
20, 21, 19, 32};
return node_count[i];
}
int predef_symbol_count(int i) /*;predef_symbol_count*/
{
static int symbol_count[15] = {0,31, 13, 61, 0, 88, 0, 409, 1, 83, 1,
5, 0 ,4 ,1};
return symbol_count[i];
}
int retrieve(char *name) /*;retrieve*/
{
char *fname;
/*
* If the unit 'name' has not previously been read from
* an AIS file, the file is read and its the unit's contents added
* to the compilation maps.
*/
#ifdef TBSN
if (getdebug) TO_ERRFILE(strjoin("RETRIEVE ", name));
#endif
fname = lib_unit_get(name);
if (fname == NULL) return FALSE;
if (!streq(fname, AISFILENAME) && !in_aisunits_read(name)){
if (read_ais(fname, FALSE, name, 0, TRUE) == NULL) {
return FALSE; /* Message emitted by READ_AIS.*/
}
}
return TRUE;
}
int last_comp_index(IFILE *ifile) /*;last_comp_index*/
{
/* determine the number of comp units in ifile. */
long rec;
int i;
i=0;
for (rec=read_init(ifile); rec!=0; rec=read_next(ifile,rec)) i++;
return i;
}
int stub_retrieve(char *name) /*;stub_retrieve*/
{
char *fname;
Tuple stubtup, tup;
int si, n, i;
/*
* Reads, if necessary, information from the file in which the stub
* 'name' was declared.
*/
#ifdef TBSN
if (putdebug) TO_ERRFILE(strjoin("STUB_RETRIEVE ", name));
#endif
fname = lib_stub_get(name);
if (fname == NULL) return FALSE;
if (!streq(fname, AISFILENAME)) {
si = stub_numbered(name);
stubtup = (Tuple) stub_info[si];
tup = (Tuple) stubtup[4];
n = tup_size(tup);
for (i = 1;i <= n; i++) {
retrieve(pUnits[(int)tup[i]]->name);
}
if (!read_stub(fname, name, "st1")) return FALSE;
}
return TRUE;
}
void update_lib_maps(char *name, char unit_typ) /*;update_lib_maps*/
{
char *uname, *body, *typ, *other, *unit;
int i;
/*
* Add current unit -name- to lib map, and remove references in
* library maps to previously compiled units with the same name.
*
* The effect of constant map 'remove' in SETL version is achieved
* in C using procedure update_lib_maps_remove, which is to be
* found after this procedure.
*/
uname = unit_name_type(name);
if (unit_typ == 'u') {
if (streq(uname , "sp") && lib_unit_get(name) != NULL) {
body = strjoin("bo", unit_name_names(name));
if (lib_unit_get(body) != NULL)
lib_unit_put(body, NULL);
}
/*
* If no other units points to the AISCODE in question, remove it
* from LIB_AIS. In principle, something analoguous should may be done
* for systems that allows deletion of a file.
*/
lib_unit_put(name, AISFILENAME);
for (i = 1;i <= 2; i++) {
typ = update_lib_maps_remove(uname, i);
/*(forall typ in (remove(name(1)) ? {}) )*/
if (typ == NULL) continue;
/*other := [typ] + name(2..);*/
other = strjoin(typ, unit_name_names(name));
if (lib_unit_get(other) != NULL) {
lib_unit_put(other, NULL);
empty_unit_slots++;
}
}
}
else if (unit_typ == 's') {
lib_stub_put(name, AISFILENAME);
i